/**
 * 
 */
package com.gragra.util;
import java.util.Arrays;
/**
 * This class provides some static methods that can be used to process multi-level arrays in the way that 
 * java.util.Arrays allows for the processing of single level arrays.
 * @author Christoph Teichmann
 * created Dec 23, 2012 7:36:42 PM
 * @version 0.1
 */
public class ArraysExtended
{
	/**
	 * When given a single level array this method returns a string representation like the one given by 
	 * Arrays.toString(arr). Otherwise it recursively calls itself to generate a string that represents the
	 * array down to the lowest level.
	 *
	 * @param arr
	 * @return
	 */
	public static String toString(Object[] arr)
	{
		if(arr == null)
		{return "null";}
		StringBuilder ret = new StringBuilder();
		ret.append("[");
		boolean first = true;
		for(Object o : arr)
		{
			if(first)
			{first = false;}
			else
			{ret.append(",");}
			ret.append(" ");
			if(o == null)
			{
				ret.append("null");
				continue;
			}
			if(o.getClass().isArray())
			{
				if(o instanceof Object[])
				{ret.append(toString((Object[]) o));}
				if(o instanceof int[])
				{ret.append(Arrays.toString((int[]) o));}
				if(o instanceof boolean[])
				{ret.append(Arrays.toString((boolean[]) o));}
				if(o instanceof double[])
				{ret.append(Arrays.toString((double[]) o));}
				if(o instanceof short[])
				{ret.append(Arrays.toString((short[]) o));}
				if(o instanceof long[])
				{ret.append(Arrays.toString((long[]) o));}
				if(o instanceof float[])
				{ret.append(Arrays.toString((float[]) o));}
				if(o instanceof byte[])
				{ret.append(Arrays.toString((byte[]) o));}
				if(o instanceof char[])
				{ret.append(Arrays.toString((char[]) o));}
			}
			else
			{ret.append(o.toString());}
		}
		ret.append(" ]");
		return ret.toString();
	}
	/**
	 * returns a deep copy of the given array.
	 *
	 * @param of
	 * @return
	 */
	public static Object[] DeepCopy(Object[] of)
	{
		int length = of.length;
		Object[] copy = Arrays.copyOf(of,length);
		for (int i = 0; i < of.length; i++)
		{
			Object element = of[i];
			if(element.getClass().isArray())
			{
				if(element instanceof Object[])
				{copy[i] = DeepCopy((Object[]) element);}
				if(element instanceof int[])
				{copy[i] = Arrays.copyOf((int[]) element,((int[]) element).length);}
				if(element instanceof boolean[])
				{copy[i] = Arrays.copyOf((boolean[]) element,((boolean[]) element).length);}
				if(element instanceof double[])
				{copy[i] = Arrays.copyOf((double[]) element,((double[]) element).length);}
				if(element instanceof short[])
				{copy[i] = Arrays.copyOf((short[]) element,((short[]) element).length);}
				if(element instanceof long[])
				{copy[i] = Arrays.copyOf((long[]) element,((long[]) element).length);}
				if(element instanceof float[])
				{copy[i] = Arrays.copyOf((float[]) element,((float[]) element).length);}
				if(element instanceof byte[])
				{copy[i] = Arrays.copyOf((byte[]) element,((byte[]) element).length);}
				if(element instanceof char[])
				{copy[i] = Arrays.copyOf((char[]) element,((char[]) element).length);}
			}
		}
		return copy;
	}
}